<script lang="tsx" setup>
import {onMounted, reactive, ref, h, resolveComponent} from 'vue'
import {
  ElContainer,
  ElHeader,
  ElMain,
  ElFooter,
  ElButton,
  ElCol,
  ElRow,
  ElMessage,
  ElPopover,
  ElCheckbox,
  ElIcon,
  TableV2FixedDir,
  ElInput
} from 'element-plus'
import request from '../utils/request';
import {Filter} from '@element-plus/icons-vue'
import type {HeaderCellSlotProps} from 'element-plus'


defineProps({
  msg: String,
})

// 定义配置信息
const config = reactive({
  enableProxy: false,
  enableProxyLoading: true,
  localFilter: [],
  enableSystemProxy: false,
  enableSystemProxyLoading: true,
  systemProxyPort: 18443,
  systemProxyPortView: 18443,
})
// 定义数据信息
const originalTableData = [] // 以时间顺序的方式存储
const data = reactive({
  tableData: [], // 以时间倒序的方式存储
})

// 定义table表格头信息
let tableColumns = [
  {
    prop: 'id',
    label: 'ID',
    width: 50,
  },
  {
    prop: 'uriHead',
    label: 'protocol(code)',
    width: 200,

  },
  {
    prop: 'remoteHost',
    label: 'remoteHost',
    width: 150,
  },
  {
    prop: 'method',
    label: 'method',
    width: 80,
  },
  {
    prop: 'uri',
    label: 'uri',
    width: 150,
  },
  {
    prop: 'requestContentType',
    label: 'Request Content Type',
    width: 250,
  },
  {
    prop: 'requestContentLen',
    label: 'Request Content Length( byte )',
    width: 150,
  },
  {
    prop: 'time',
    label: 'time consuming',
    width: 150,
  },
  {
    prop: 'responseContentType',
    label: 'Response Content Type',
    width: 250,
  },
  {
    prop: 'responseContentLen',
    label: 'Response Content Length( byte )',
    width: 150,
  },
]

// 定义页面查询的过滤器信息
const filterConfig = {
  filterRecord: record => {
    if (filterConfig.uriHead.http.value && record.uriHead === 'http'
        || filterConfig.uriHead.https.value && record.uriHead === 'https') {
      return true;
    }
    if (record.remoteHost.indexOf(filterConfig.remoteHost.host.value) > 0) {
      return true;
    }
    if (record.uri.indexOf(filterConfig.uri.value) > 0) {
      return true;
    }
    return false;
  },
  onFilter: () => {
    if (!filterConfig.hasFilterCondition()) {
      return
    }
    let tempTable = []
    originalTableData.forEach((item, index) => {
      if (filterConfig.filterRecord(item)) {
        tempTable.unshift(item)
      }
    })
    data.tableData.splice(0, data.tableData.length);// 清空数组
    data.tableData.push(...tempTable)//将过滤到的数据全部添加到新的数组中去
  },
  hasFilterCondition: () => {
    if (filterConfig.uriHead.http.value || filterConfig.uriHead.https.value) {
      return true;
    }
    if (filterConfig.remoteHost.host.value) {
      return true;
    }

    if (filterConfig.uri.value) {
      return true;
    }
    return false;
  },
  uriHead: {
    http: ref(false),
    https: ref(false),
  },
  remoteHost: {
    host: ref('')
  },
  uri: ref('')
}
const getTableColumns = tableColumns.map(item => {
  return {
    key: item.prop,
    dataKey: item.prop,
    title: item.label,
    width: item.width ? item.width : 100,
    align: 'center',
    headerCellRenderer: item.headerCellRenderer ? item.headerCellRenderer : undefined
  }
})
const getTableColumnsByKey = key => {
  for (let i = 0; i < getTableColumns.length; i++) {
    if (getTableColumns[i].key === key) {
      return getTableColumns[i];
    }
  }
}
// getTableColumnsByKey('uriHead').headerCellRenderer = (props) => {
//   return (
//       <div class="flex items-center justify-center">
//         <span class="mr-2 text-xs">{props.column.title}</span>
//         <ElPopover trigger="click" width="120px">
//           {{
//             default: () => (
//                 <div class="filter-wrapper">
//                   <div class="filter-group">
//                     <ElCheckbox v-model={filterConfig.uriHead.http.value}>http</ElCheckbox>
//                     <ElCheckbox v-model={filterConfig.uriHead.https.value}>https</ElCheckbox>
//                   </div>
//                   <div class="el-table-v2__demo-filter">
//                     <ElButton type="success" onClick={filterConfig.onFilter}>Confirm</ElButton>
//                   </div>
//                 </div>
//             ),
//             reference: () => (
//                 <ElIcon class="cursor-pointer">
//                   <Filter/>
//                 </ElIcon>
//             ),
//           }}
//         </ElPopover>
//       </div>
//   )
// }


getTableColumnsByKey('remoteHost').headerCellRenderer = (props) => {
  return (
      <div class="flex items-center justify-center">
        <span class="mr-2 text-xs">{props.column.title}</span>
        <ElPopover trigger="click" width="120px">
          {{
            default: () => (
                <div class="filter-wrapper">
                  <div class="filter-group">
                    <ElInput v-model={filterConfig.remoteHost.host.value}/>
                  </div>
                  <div class="el-table-v2__demo-filter">
                    <ElButton type="success" onClick={filterConfig.onFilter}>Confirm</ElButton>
                  </div>
                </div>
            ),
            reference: () => (
                <ElIcon class="cursor-pointer">
                  <Filter/>
                </ElIcon>
            ),
          }}
        </ElPopover>
      </div>
  )
}

getTableColumnsByKey('uri').headerCellRenderer = (props) => {
  return (
      <div class="flex items-center justify-center">
        <span class="mr-2 text-xs">{props.column.title}</span>
        <ElPopover trigger="click" width="120px">
          {{
            default: () => (
                <div class="filter-wrapper">
                  <div class="filter-group">
                    <ElInput v-model={filterConfig.uri.value}/>
                  </div>
                  <div class="el-table-v2__demo-filter">
                    <ElButton type="success" onClick={filterConfig.onFilter}>Confirm</ElButton>
                  </div>
                </div>
            ),
            reference: () => (
                <ElIcon class="cursor-pointer">
                  <Filter/>
                </ElIcon>
            ),
          }}
        </ElPopover>
      </div>
  )
}

getTableColumns.push({
  key: 'operations',
  title: 'Operations',
  // cellRenderer: ({ cellData, rowData }) => <>
  //     <ElButton size="small" type="success" v-on:click="viewRequestContent(rowData)" >请求数据</ElButton>
  //     <ElButton size="small" type="danger" click="viewResponseContent(rowData)" >响应数据</ElButton>
  // </>,
  cellRenderer: ({cellData, rowData}) =>
      h(
          'div',
          {},
          [
            h(ElButton,
                {onClick: () => viewRequestContent(rowData), type: "success", size: "small"},
                {default: () => "请求数据"},
            ), h(ElButton,
              {onClick: () => viewResponseContent(rowData), type: "danger", size: "small"},
              {default: () => "响应数据"},
          )
          ]
      ),
  width: 200,
  align: 'center',
  flexGrow: 1,
})

const getTableData = async () => {
  const eventSource = new EventSource(request.baseURL + '/settings/records');
  eventSource.onmessage = event => {
    try {
      // 构建record
      const newRecord = JSON.parse(event.data);
      newRecord.remoteHost = newRecord.remoteHost + ':' + newRecord.remotePort
      if (newRecord.updateTime > 0 && newRecord.createTime > 0) {
        newRecord.time = (newRecord.updateTime - newRecord.createTime) + 'ms'
      } else {
        newRecord.time = 'padding'
      }
      if (newRecord.responseStatus || newRecord.responseStatus===0){
        newRecord.uriHead = `${newRecord.uriHead}(${newRecord.responseStatus})`
      }




      // 添加到全局的record数组中
      if (newRecord.status === 'padding') {
        originalTableData.push(newRecord)
      } else if (newRecord.status === 'complete') {
        originalTableData.forEach((item, index) => {
          if (item.id === newRecord.id) {
            originalTableData[index] = newRecord;
          }
        })
      }

      // 根据条件判断是否需要加入展示的数组中
      if (!filterConfig.hasFilterCondition() || filterConfig.filterRecord(newRecord)) {
        if (newRecord.status === 'padding') {
          data.tableData.unshift(newRecord);// 往数组的最前面添加数据
        } else if (newRecord.status === 'complete') {
          for (let i = 0; i < data.tableData.length; i++) {
            if (data.tableData[i].id === newRecord.id) {
              data.tableData.splice(i, 1, newRecord);
              break
            }
          }
        }
      }

    } catch (error) {
      console.error('数据处理异常 onmessage', error, event);
    }
  };
  eventSource.onerror = (error) => {
    console.error('获取数据异常 onerror', error);
    eventSource.close();
    setTimeout(getTableData, 2000);
  };
}
const initConfig = async () => {
  config.enableProxyLoading = true
  config.enableSystemProxyLoading = true

  request.get('/settings/getConfig').then(res => {
    if (res.code === 200) {
      config.enableProxy = res.data.proxyStarted
      config.enableSystemProxy = res.data.systemcProxyOpened
      config.enableProxyLoading = false
      config.enableSystemProxyLoading = false
    } else {
      ElMessage.success(res.msg)
    }
  }).catch(reason => {
    setTimeout(initConfig, 2000)
  })
}
const viewRequestContent = item => {
  if (item.requestContentLen > 0) {
    let jumpUrl = `${request.baseURL}/settings/record/viewRequestContent?id=${item.id}`
    window.open(jumpUrl, '_blank')
  } else {
    ElMessage.warning('暂无请求 content')
  }
}
const viewResponseContent = item => {
  if (item.responseContentLen > 0) {
    let jumpUrl = `${request.baseURL}/settings/record/viewResponseContent?id=${item.id}`
    window.open(jumpUrl, '_blank')
  } else {
    ElMessage.warning('暂无响应的 content')
  }
}


const changeProxyServerConfig = async () => {
  return new Promise((resolve, reject) => {
    config.enableProxyLoading = true
    const url = config.enableProxy ? '/settings/stop' : '/settings/start'
    request.post(url).then(res => {
      config.enableProxyLoading = false
      if (res.code === 200) {
        initConfig()
        resolve(true)
        ElMessage.success('操作成功')
      } else {
        ElMessage.success(res.msg)
        reject(new Error(res.msg))
      }
    }).finally(() => {
      config.enableProxyLoading = false
    })
  })
}

const changeSystemProxyConfig = async () => {
  return new Promise((resolve, reject) => {
    config.enableSystemProxyLoading = true
    request.postForm('/settings/setOpenSystemProxy', null, {
      openSystemProxy: !config.enableSystemProxy
    }).then(res => {
      config.enableSystemProxyLoading = false
      if (res.code === 200) {
        initConfig()
        resolve(true)
        ElMessage.success('操作成功')
      } else {
        ElMessage.success(res.msg)
        reject(new Error(res.msg))
      }
    }).finally(() => {
      config.enableSystemProxyLoading = false
    })
  })
}

onMounted(() => {
  initConfig()
  getTableData()
})
</script>

<template>
  <div class="common-layout">
    <el-container class="common-container">
      <el-header class="common-header">
        <el-row>
          <el-col :span="4">
            <el-text class="mx-1">Proxy Server</el-text>
            <el-switch v-model="config.enableProxy" :loading="config.enableProxyLoading"
                       :before-change="changeProxyServerConfig"/>
          </el-col>
          <el-col :span="4">
            <el-text class="mx-1">System Proxy</el-text>
            <el-switch v-model="config.enableSystemProxy" :loading="config.enableSystemProxyLoading"
                       :before-change="changeSystemProxyConfig"/>
          </el-col>
          <el-col :span="4">
            <el-text class="mx-1">System Proxy Port({{ config.systemProxyPort }})</el-text>
            <el-input v-model="config.systemProxyPortView"/>
            <el-button v-show="!config.enableSystemProxy"
                       v-on:click="config.systemProxyPort=config.systemProxyPortView">修改端口
            </el-button>
          </el-col>
        </el-row>
      </el-header>
      <el-main class="common-main">
        <el-auto-resizer>
          <template #default="{ height, width }">
            <el-table-v2 :columns="getTableColumns" :data="data.tableData" :width="width" :height="height"
                         fixed/>
          </template>
        </el-auto-resizer>
      </el-main>
    </el-container>
  </div>
</template>

<style scoped>
.common-header {
  height: 150px;
  background-color: #f5f5f5;
}

/* 將 el-main 填充整个下方的高度 */
.common-container {
  height: 850px;
}
</style>
